﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using ST.Buz.Service;
using ST.Common.Util;
using ST.Common.Util.Mvc;
using ST.Common.Util.Text;
using ST.WX.Common.Exceptions;
using ST.WX.Common.Pay;
using ST.WX.XCX;
using System;
using System.IO;
using System.Text;

namespace ST.Buz.Api.Controllers
{
    /// <summary>
    /// 
    /// </summary>
    [AllowAnonymous]
	[Route("wx/payorder")]
	public class WX_PayOrderController : BaseController
	{
		private readonly IServiceWXPayOrder service;
		private readonly WXXCXBaseApi xcxBaseApi;
		//private readonly ISessionService sessionServ;
		private readonly IServiceWXAppConfig wxAppConfigServ;

		public WX_PayOrderController(ILogger<WX_PayOrderController> _logger
			, IServiceWXPayOrder _service
			, WXXCXBaseApi _xcxBaseApi
			, IServiceWXAppConfig _wxAppConfigServ
			) : base(_logger)
		{
			service = _service;
			xcxBaseApi = _xcxBaseApi;
			wxAppConfigServ = _wxAppConfigServ;
		}

		/// <summary>
		/// 微信支付结果通知
		/// </summary>
		[HttpPost("result")]
		public IActionResult ResultNotify()
		{
			var retNotifyResult = new WXPayNotifyResultRet();
			try
			{
				string xml = string.Empty;

				//Request.EnableRewind();//如果想让Request.Body可以再次读取的话需要调用
				//					   //Request.Body.Seek(0, SeekOrigin.Begin);
				//using (StreamReader sr = new StreamReader(Request.Body, Encoding.UTF8, true, 1024, true))
				//{
				//	xml = sr.ReadToEnd();
				//}
				//// Rewind, so the core is not lost when it looks the body for the request
				//Request.Body.Position = 0;//重置stream位置
				using (StreamReader sr = new StreamReader(Request.Body, Encoding.UTF8))
				{
					xml = sr.ReadToEnd();
				}
				if (string.IsNullOrEmpty(xml))
				{
					throw new BuzException("微信支付结果通知返回内容为空");
				}

				retNotifyResult.Parse(xml);
				var appConfig = wxAppConfigServ.LoadOrGet(retNotifyResult.appid);
				retNotifyResult.Validate(appConfig.MchKey);
				if (logger.IsEnabled(LogLevel.Debug))
				{
					logger.LogDebug("微信支付结果通知返回：{0}，解析结果：{1}", xml, TextHelper.SerializeObject(retNotifyResult));
				}

				var payOrder = service.GetByOutTradeNo(retNotifyResult.out_trade_no, true);
				payOrder.Attach = retNotifyResult.attach;
				payOrder.BankType = retNotifyResult.bank_type;
				payOrder.CashFee = retNotifyResult.cash_fee;
				payOrder.CouponCount = retNotifyResult.coupon_count;
				payOrder.CouponFee = retNotifyResult.coupon_fee;
				payOrder.DeviceInfo = retNotifyResult.device_info;
				payOrder.MchID = retNotifyResult.mch_id;
				payOrder.OpenID = retNotifyResult.openid;
				//payOrder.OutTradeNO = data.out_trade_no;
				//payOrder.PrepayID = data.pre;
				payOrder.SettlementTotalFee = retNotifyResult.settlement_total_fee;
				payOrder.TimeEnd = retNotifyResult.time_end;
				//payOrder.TimeStart = data.times;
				payOrder.TotalFee = retNotifyResult.total_fee;
				payOrder.TradeState = retNotifyResult.result_code;
				payOrder.TradeStateDesc = string.IsNullOrEmpty(retNotifyResult.err_code) && string.IsNullOrEmpty(retNotifyResult.err_code_des) ? string.Empty : (retNotifyResult.err_code + ":" + retNotifyResult.err_code_des);
				payOrder.TradeType = retNotifyResult.trade_type;
				payOrder.TransactionID = retNotifyResult.transaction_id;
				service.Update(payOrder);

				return Content(retNotifyResult.ResponseSuccess());
			}
			catch (WXPayException ex)
			{
				logger.LogError(ex, ex.InnerException != null ? ex.InnerException.Message : ex.Message);
				return Content(retNotifyResult.ResponseFail(ex.Message));
			}
			catch (Exception ex)
			{
				logger.LogError(ex, ex.InnerException != null ? ex.InnerException.Message : ex.Message);
				return Content(retNotifyResult.ResponseFail(ex.Message));
			}
		}
		#region 辅助方法

		/// <summary>
		/// 当前请求的小程序AppID
		/// </summary>
		protected virtual string RequestAppID
		{
			get { return GetRequestAppID(); }
		}
		#endregion
	}
}